/* 
 * File:   Heuristic.h
 * Author: Guilherme Monteiro
 *
 */

#ifndef HEURISTIC_H
#define	HEURISTIC_H

#include <cstdlib>
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
#include <string>
#include <algorithm>
#include <exception>

#include "NullImageException.h"
#include "ImageColorInverter.h"
#include "RotationCorrector.h"
#include "GenericModel.h"
#include "ImageSaver.h"
#include "ImageDilatator.h"
#include "ROI.h"
#include "ImageNoisesExtractor.h"
#include "FilterLines.h"
#include "Line.h"

using namespace std;

/**
 * Class that represents an
 * heuristic.
 * 
 * @author Guilherme Monteiro
 */
class Heuristic {
public:
    Heuristic(ROI* r, MetaInfo* meta, GenericModel* model);
    Heuristic(const Heuristic& orig);
    virtual ~Heuristic();
    void configureHeuristicROI();
    
    vector< vector<Line> > transcribeLines();
    
    void setHorizontalForegroundLines(vector<Line> horizontalForegroundLines);
    vector<Line> getHorizontalForegroundLines();
    void setHorizontalBackgroundLines(vector<Line> horizontalBackgroundLines);
    vector<Line> getHorizontalBackgroundLines();
    void setVerticalForegroundLines(vector<Line> verticalForegroundLines);
    vector<Line> getVerticalForegroundLines();
    void setVerticalBackgroundLines(vector<Line> verticalBackgroundLines);
    vector<Line> getVerticalBackgroundLines();
private:
    FilterLines* filter;
    ROI* _roi;
    MetaInfo* meta;
    GenericModel *model;
    IplImage* imageROIWithoutDilatation;
    
    vector<int> verticalProjection;
    vector<int> horizontalProjection;
    
    int maximumVertical;
    int minimumVertical;
    int maximumHorizontal;
    int minimumHorizontal;
    
    // final vectors with lines and table borders
    vector<Line> verticalLines;
    vector<Line> horizontalLines;
    
    // intermediary vectors with lines detected and filtered
    vector<Line> horizontalForegroundLines;
    vector<Line> horizontalBackgroundLines;
    vector<Line> verticalForegroundLines;
    vector<Line> verticalBackgroundLines;
    
    int getMaximum(vector<int> vec);
    int getMinimum(vector<int> vec);
    
    void adaptAndSaveImageROICut(ROI* roi);
protected:
    void setROI(ROI* r);
    ROI* getROI();
    
    FilterLines* getFilter();
    
    vector<Line> detectHorizontalLines();
    vector<Line> detectVerticalLines();
    
    vector<Line> detectForegroundHorizontalLines();
    vector<Line> detectBackgroundHorizontalLines() throw (NullImageException);
    vector<Line> detectForegroundVerticalLines();
    vector<Line> detectBackgroundVerticalLines();
    
    vector<int> getVerticalProjection();
    void setVerticalProjection(vector<int> verticalProjection);
    vector<int> getHorizontalProjection();
    void setHorizontalProjection(vector<int> horizontalProjection);
    
    vector<Line> getVerticalLines();
    void setVerticalLines(vector<Line> verticalLines);
    vector<Line> getHorizontalLines();
    void setHorizontalLines(vector<Line> horizontalLines);
    
    int getMaximumVertical();
    void setMaximumVertical(int max);
    int getMaximumHorizontal();
    void setMaximumHorizontal(int max);
    int getMinimumVertical();
    void setMinimumVertical(int min);
    int getMinimumHorizontal();
    void setMinimumHorizontal(int min);
    
    void saveImageROI(IplImage* imgROI); // log image
};

#endif	/* HEURISTIC_H */

